﻿using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using eProject.ViewModel;
using eProject.ViewModel.Commands;

namespace eProject.View
{
    /// <summary>
    /// Interaction logic for EmployeesView.xaml
    /// </summary>
    public partial class EmployeesView : INotifyPropertyChanged
    {
        public EmployeesView()
        {
            InitializeComponent();

        }

        public static readonly DependencyProperty ManagerProperty = DependencyProperty.Register("Manager",
                                                                                                                  typeof(
                                                                                                                      CommonManager
                                                                                                                      ),
                                                                                                                  typeof(
                                                                                                                      EmployeesView)
                                                                                                                 );

        public static readonly DependencyProperty CommandsQueueProperty =
            DependencyProperty.Register("CommandsQueue", typeof(CommandsQueue), typeof(EmployeesView));

        public static readonly DependencyProperty OwnerWindowProperty =
            DependencyProperty.Register("OwnerWindow", typeof(Window), typeof(EmployeesView));

        public CommandsQueue CommandsQueue
        {
            get { return (CommandsQueue)GetValue(CommandsQueueProperty); }
            set { SetValue(CommandsQueueProperty, value); }
        }

        public CommonManager Manager
        {
            get { return (CommonManager)GetValue(ManagerProperty); }
            set { SetValue(ManagerProperty, value); }
        }

        public Window OwnerWindow
        {
            get { return (Window)GetValue(OwnerWindowProperty); }
            set { SetValue(OwnerWindowProperty, value); }
        }

        public enum Modes
        {
            Left, Right
        }

        private Modes _mode = Modes.Left;

        public Modes Mode
        {
            get { return _mode; }
            set
            {
                if (_mode == value) return;
                _mode = value;
                RefreshMode();
                InvokePropertyChanged("Mode");
            }
        }

        private void RefreshMode()
        {
            switch (Mode)
            {
                case Modes.Left:
                    IsUntouchable = false;
                    ShowButtons = true;
                    listBox.Background = Brushes.LightGray;
                    break;
                case Modes.Right:
                    IsUntouchable = true;
                    ShowButtons = false;
                    listBox.Background = FindResource("grayStripedBrush") as Brush;
                    break;
            }
        }

        public bool ShowButtons
        {
            get { return buttonsPanel.Visibility == Visibility.Visible; }
            set
            {
                if (value == (buttonsPanel.Visibility == Visibility.Visible)) return;
                buttonsPanel.Visibility = value ? Visibility.Visible : Visibility.Hidden;
                InvokePropertyChanged("ShowButtons");//TODO remove event?
            }
        }

        public bool IsUntouchable
        {
            get { return rectangle.Visibility == Visibility.Visible; }
            set
            {
                if (value == (rectangle.Visibility == Visibility.Visible)) return;
                rectangle.Visibility = value ? Visibility.Visible : Visibility.Hidden;
                InvokePropertyChanged("IsUntouchable");//TODO remove event?
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void InvokePropertyChanged(string property)
        {
            PropertyChangedEventHandler changed = PropertyChanged;
            if (changed != null) changed(this, new PropertyChangedEventArgs(property));
        }


        public event SelectionChangedEventHandler SelectionChanged
        {
            add { listBox.SelectionChanged += value; }
            remove { listBox.SelectionChanged -= value; }
        }


        private void CommandBinding_DeleteCommand(object sender, ExecutedRoutedEventArgs e)
        {
            var item = listBox.SelectedItem;
            var empl = item as EmployeeViewModel;
            if (empl == null) return;
            CommandsQueue.Do(new DeleteEmployeeCommand(Manager, empl));
        }

        private void CommandBinding_CreateCommand(object sender, ExecutedRoutedEventArgs e)
        {
            var dialog = new CreateEmployeeDialog(Manager){Owner = OwnerWindow};
            var result = dialog.ShowDialog();
            if (result == true)
            {
                var name = dialog.EmployeeName;
                var surname = dialog.EmployeeSurname;
                var phone = dialog.EmployeePhone;
                var email = dialog.EmployeeEmail;
                CommandsQueue.Do(new CreateEmployeeCommand(Manager, name, surname, phone, email));
            }
        }

        private void CommandBinding_DeleteCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (listBox == null) return;
            var item = listBox.SelectedItem;
            var empl = item as EmployeeViewModel;
            e.CanExecute = empl != null && Manager.Activities.Where(a => a.Employee == empl).Count() == 0 && Manager.ScheduleItems.Where(s=>s.Employees.Contains(empl)).Count() == 0;
        }

        private void CommandBinding_MoveUpCommand(object sender, ExecutedRoutedEventArgs e)
        {
            var index = listBox.SelectedIndex;
            CommandsQueue.Do(new SwitchItemsCommand<EmployeeViewModel>(Manager.SwitchEmployees, Manager.Employees[index], Manager.Employees[index - 1]));
        }

        private void CommandBinding_MoveUpCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (listBox == null) return;
            var index = listBox.SelectedIndex;
            e.CanExecute = index > 0;
        }

        private void CommandBinding_MoveDownCommand(object sender, ExecutedRoutedEventArgs e)
        {
            var index = listBox.SelectedIndex;
            CommandsQueue.Do(new SwitchItemsCommand<EmployeeViewModel>(Manager.SwitchEmployees, Manager.Employees[index], Manager.Employees[index + 1]));
        }

        private void CommandBinding_MoveDownCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (listBox == null) return;
            var index = listBox.SelectedIndex;
            e.CanExecute = index < listBox.Items.Count - 1 && index >= 0;
        }

        private void listBox_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Keyboard.Focus(listBox);
        }


        private void CommandBinding_EditCommand(object sender, ExecutedRoutedEventArgs e)
        {
            var employee = listBox.SelectedItem as EmployeeViewModel;
            if (employee == null) return;
            var dialog = new CreateEmployeeDialog(Manager, employee) {Owner = OwnerWindow};
            var result = dialog.ShowDialog();
            if (result == true)
            {
                var name = dialog.EmployeeName;
                var surname = dialog.EmployeeSurname;
                var email = dialog.EmployeeEmail;
                var phone = dialog.EmployeePhone;
                CommandsQueue.Do(new ChangeEmployeeCommand(Manager, employee, name, surname, phone, email));
            }
        }

        private void CommandBinding_EditCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (listBox == null) return;
            var item = listBox.SelectedItem;
            var empl = item as EmployeeViewModel;
            e.CanExecute = empl != null;
        }
    }
}
